package math

import "math"
import "jvmgo/ch08/instructions/base"
import "jvmgo/ch08/rtda"

/*
    int long double float的求余操作
 */

// double求余
type DREM struct {
    base.NoOperandsInstruction
}

func (self *DREM) Execute(frame *rtda.Frame) {
    stack := frame.OperandStack()
    v2 := stack.PopDouble()
    v1 := stack.PopDouble()
    result := math.Mod(v1, v2)
    stack.PushDouble(result)
}

// float求余
type FREM struct {
    base.NoOperandsInstruction
}

func (self *FREM) Execute(frame *rtda.Frame) {
    stack := frame.OperandStack()
    v2 := stack.PopFloat()
    v1 := stack.PopFloat()
    result := float32(math.Mod(float64(v1), float64(v2)))
    stack.PushFloat(result)
}

// int求余
type IREM struct {
    base.NoOperandsInstruction
}

func (self *IREM) Execute(frame *rtda.Frame) {
    stack := frame.OperandStack()
    v2 := stack.PopInt()
    v1 := stack.PopInt()
    if v2 == 0 {
        panic("java.lang.ArithmeticException: / by zero")
    }

    result := v1 % v2
    stack.PushInt(result)
}

// long求余
type LREM struct {
    base.NoOperandsInstruction
}

func (self *LREM) Execute(frame *rtda.Frame) {
    stack := frame.OperandStack()
    v2 := stack.PopLong()
    v1 := stack.PopLong()
    if v2 == 0 {
        panic("java.lang.ArithmeticException: / by zero")
    }

    result := v1 % v2
    stack.PushLong(result)
}
